﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ReactiveUI.Fody.Helpers;
using S7.Net.Types;
using ReactiveUI;
using System.Reactive;
using Common.Utils;

namespace Common.ViewModels
{
    /// <summary>
    /// 工位的 X Y Z位置(槽位,不动,槽位不一定属于池子,可能有空的槽位，槽位也叫工位,在上个系统中,工位和站点是1对一的关系,一个站点可以有多个工位,一个工位在不同通道有不同站点)
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class WorkStation : ViewModelBase
    {

        /// <summary>
        /// 工位名称
        /// </summary>
        [Reactive] public string Name { get; set; }

        /// <summary>
        /// 赤池子
        /// </summary>
        [Reactive] public 池子 池子 { get; set; }

        /// <summary>
        /// 工位是否启用(一旦工位启用就有用，否则就无用)
        /// </summary>
        [Reactive] public bool IsUse { get; set; }

        /// <summary>
        /// 工位ID
        /// </summary>
        [Reactive] public int ID { get; set; }

        ///// <summary>
        ///// 工位类型
        ///// </summary>
        //[Reactive] public 工位类型 工位类型 { get; set; }

        [Reactive] public bool IsContinueRun { get; set; } = true;


        /// <summary>
        /// 工位位置(世界坐标系)
        /// </summary>
        [Reactive] public Point3D Point3D { get; set; }=new Point3D();

        /// <summary>
        /// 工位位置(相对于箱体的位置,相对于箱体左上角,可以根据箱体坐标算出工位的坐标系)
        /// </summary>
        [Reactive] public Point3D 相对箱体位置 { get; set; }=new Point3D();

        /// <summary>
        /// 工位站点位置(摆渡上站点位置,先到站点 后到具体位置)
        /// </summary>
        [Reactive] public BoatStation BoatStation { get; set; }

        /// <summary>
        /// 工位工位上站点位置(锚定站点,水平方向) 
        /// </summary>
        [Reactive] public Station Station { get; set; }

        /// <summary>
        /// 工位工位上站点位置(锚定站点,主通道方向,只有上下料两个位置有) 
        /// </summary>
        [Reactive] public Station MainThroughStation { get; set; }

        /// <summary>
        /// 加锁(锁定的槽位,标识占位，占位之后不可被使用)
        /// </summary>
        [Reactive]
        [JsonIgnore]
        public bool IsLock { get; set; }

        [Reactive]
        [JsonIgnore]
        public 工件 当前工件 { get; set; }
        
        [Reactive]
        [JsonIgnore]
        public bool 是否有料 { get; set; }=false;

        [Reactive]
        [JsonIgnore]
        public bool IsWaitMove { get; set; } = false;

        public WorkStation()
        {
            MessageAggregator<LoadedMsg>.Subscribe(OnLoadedMsg);
        }


        private void OnLoadedMsg(LoadedMsg obj)
        {
            if (池子 != null)
            {
                this.Point3D.X = 池子.PointStartBase.X + 相对箱体位置.X;
                this.Point3D.Y = 池子.PointStartBase.Y + 相对箱体位置.Y;
                this.Point3D.Z = 池子.PointStartBase.Z + 相对箱体位置.Z;
            }
           
        }

        /// <summary>
        /// 新增工件
        /// </summary>
        /// <param name="工件"></param>
        public void Add工件(工件 工件)
        {
            this.当前工件 = 工件;
            this.是否有料 = true;
            工件.CurrentWorkStation=this;
            工件.CurrentStation = 工件.CurrentWorkStation.Station;
        }

        public void Remove工件()
        {
            this.当前工件 = null;
            this.是否有料 = false;
        }
    }



    public class 工位类型 : BaseViewModel
    {
        /// <summary>
        /// 工位类型名称
        /// </summary>
        [Reactive] public string Name { get; set; }

        /// <summary>
        /// 工位类型唯一标识
        /// </summary>
        [Reactive] public int ID { get; set; }

        /// <summary>
        /// 工作时间(工作时间低于某个阈值,让机械手运动完成之后不等待,单位秒)
        /// </summary>
        [Reactive] public int Time { get; set; }


        /// <summary>
        /// 机械手运动时间
        /// </summary>
        [Reactive] public int 运动时间 { get; set; }

        [Reactive] public bool 能否一直待着 { get; set; } = true;

        [JsonIgnore]
        [Reactive] public bool HaveChild { get; set; } = false;

        [JsonIgnore]
        public ReactiveCommand<Unit, Unit> Command上升 => ReactiveCommand.Create(() =>
        {
            int index = ProductLine.Instance.工位类型s.IndexOf(this);
            int currentIndex = index - 1;

            if (currentIndex >= 0)
            {
                ProductLine.Instance.工位类型s.Remove(this);
                ProductLine.Instance.工位类型s.Insert(currentIndex, this);
            }

        });

        [JsonIgnore]
        public ReactiveCommand<Unit, Unit> Command下降 => ReactiveCommand.Create(() =>
        {
            int index = ProductLine.Instance.工位类型s.IndexOf(this);
            int currentIndex = index + 1;
            if (currentIndex < ProductLine.Instance.Stations.Count)
            {
                ProductLine.Instance.工位类型s.Remove(this);
                ProductLine.Instance.工位类型s.Insert(currentIndex, this);
            }
        });

        [JsonIgnore]
        public ReactiveCommand<Unit, Unit> Command插入 => ReactiveCommand.Create(() =>
        {
            int index = ProductLine.Instance.工位类型s.IndexOf(this);
            int currentIndex = index + 1;

            if (currentIndex >= 0)
            {
                //ProductLine.Instance.工位类型s.Remove(this);
                ProductLine.Instance.工位类型s.Insert(currentIndex,new 工位类型() );
            }

        });

        [JsonIgnore]
        public ReactiveCommand<Unit, Unit> CommandDelete => ReactiveCommand.Create(() =>
        {
            int index = ProductLine.Instance.工位类型s.IndexOf(this);
            int currentIndex = index + 1;

            if (currentIndex >= 0)
            {
                //ProductLine.Instance.工位类型s.Remove(this);
                ProductLine.Instance.工位类型s.Insert(currentIndex, new 工位类型());
            }

        });
    }

    ///// <summary>
    ///// 存储工位对应的站点列表信息
    ///// </summary>
    //public class 工位表 : BaseViewModel
    //{
    //    public ObservableCollection<>
    //}




    /// <summary>
    /// 池子里面有多个工位()
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class 池子 : LineRigidBody
    {

        /// <summary>
        /// 池子所属的摆渡
        /// </summary>
        [Reactive] public PassVM 所属通道 { get; set; }

       

        [Reactive] public 工位类型 工位类型 { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        [Reactive] public string Description { get; set; }

        //这里为了方便  

        /// <summary>
        /// 工位(一个池子多个工位)
        /// </summary>
        public ObservableCollection<WorkStation> Works { get; set; } = new();

        /// <summary>
        /// 1-14之间
        /// </summary>
        [Reactive] public int 位置 { get; set; } = 1;

        /// <summary>
        /// 位置(中心点)
        /// </summary>
        [Reactive] public Point3D Point3D { get; set; }

        /// <summary>
        /// 字体大小
        /// </summary>
        [Reactive] public double FontSize { get; set; }

        /// <summary>
        /// 池子所在组(默认为1 前三个在这里)
        /// </summary>
        [Reactive]
        public int GroupID { get; set; } = 1;

        /// <summary>
        /// 添加工位
        /// </summary>
        [JsonIgnore]
        public ReactiveCommand<Unit, Unit> CommandAddWork => ReactiveCommand.Create(Create);




        /// <summary>
        /// 一个池子 两个槽位
        /// </summary>
        public void Create()
        {
          
            WorkStation workStation = new WorkStation { Name = $"{this.Name}_槽位{Works.Count + 1}", 池子 = this };
            workStation.相对箱体位置.X = -300;
            this.Works.Add(workStation);

            WorkStation workStation2 = new WorkStation { Name = $"{this.Name}_槽位{Works.Count + 1}", 池子 = this };
            workStation2.相对箱体位置.X = 10;
            this.Works.Add(workStation2);
        }


        public 池子()
        {
            this.XLength = 700;
            this.YLength = 700;
        }

        #region 上下料相关
        /*当小车放入*/

        /// <summary>
        /// 上料池
        /// </summary>
        [Reactive] public bool 是否上料池 { get; set; }=false;

        /// <summary>
        /// 下料池
        /// </summary>
        [Reactive] public bool 是否下料池 { get; set; } = false;

        /// <summary>
        /// 料的数量,这里有料即可触发机械手搬运, 有一个料就需要触发搬运机械手搬运了。这里有搬运水池1 搬运水池2. 堆料满了
        /// </summary>
        [Reactive] public int 料数 { get; set; }

        [Reactive] public 池子类型 池子类型 { get; set; } = 池子类型.工作池子;

        public static 池子类型[] 池子类型s { get; set; } = Enum.GetValues<池子类型>();

        #endregion


    }


    /// <summary>
    /// 上下料专用的()
    /// </summary>
    public class 上下料池子:池子
    {
        


    }

    public enum 池子类型
    {
        None,
        上料池子,
        下料池子,
        中途上料池子,
        中途下料池子,
        工作池子
    }



    /// <summary>
    /// 工作
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class Work : ViewModelBase
    {
        /// <summary>
        /// 
        /// </summary>
        [Reactive] public int WorkTimeMill { get; set; }

        /// <summary>
        /// 工作时间()
        /// </summary>
        [Reactive] public int WorkTime { get; set; }
    }


}
